const {
    LinValidator,
    Rule
} = require('../../core/lin-validator-v2')


const {
    User
} = require('../models/user')
const {
    LoginType,
    ArtType
} = require('../lib/enum')

const Joi = require('joi');

const validator = require('validator')

const {decrypt} = require('../../core/secret')


class PositiveIntegerValidator extends LinValidator {
    constructor() {
        super()
        this.id = [
            new Rule('isInt', '需要是正整数', {
                min: 1
            }),
        ]
    }
}

class MainContentValidator extends LinValidator {
    constructor() {
        super()
        // this.account = [
        //     new Rule('isLength', '不符合账号规则', {
        //         min: 4,
        //         max: 32
        //     })
        // ]
    }

}

class AdminChangeValidator {
    validate(ctx) {
        const schema = Joi.object({
            uid: Joi.number().required(),
            sid: Joi.number().required()
        });

        return schema.validateAsync(ctx.request.body, {abortEarly: false});
    }
}


//重置密码校验器
class UpdatePasswordValidator extends LinValidator {
    constructor() {
        super()
        this.newPassword = [
            new Rule('isLength', '密码至少6个字符', {min: 6}),
            // 密码复杂度验证：至少包含一个小写字母、一个大写字母、一个特殊字符和数字
            new Rule('matches', '密码必须包含大小写字母、特殊字符和数字',
                /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[!@#$%^&*()]).{6,}$/)
        ]
    }
}

class RegisterValidator extends LinValidator {
    constructor() {
        super()

        // this.email = [
        //     new Rule('isEmail', '不符合Email规范')
        // ]
        // this.password1 = [
        //     // 密码长度至少6个字符
        //     new Rule('isLength', '密码至少6个字符', {min: 6}),
        //     // 密码复杂度验证：至少包含一个小写字母、一个大写字母、一个特殊字符和数字
        //     new Rule('matches', '密码必须包含大小写字母、特殊字符和数字',
        //         /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[!@#$%^&*()_\-+=~`\{\}\[\]\|\\:;\"'<>,.\/?]).{6,}$/)
        // ];
        // this.password2 = this.password1
    }


    validateChineseID(vals) {
        const id = decrypt(vals.body.idcard)
        // 判断长度是否为18位
        if (id.length !== 18) {
            throw new Error('身份证位数不正确')
        }

        // 获取前17位
        const idBody = id.slice(0, 17);

        // 获取第18位
        const idChecksum = parseInt(id.slice(-1), 10);

        // 计算权重因子（Wi）数组
        const Wi = [
            7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2
        ];

        // 校验码字符值
        const validateCode = [
            1, 0, 'X', 9, 8, 7, 6, 5, 4, 3, 2
        ];

        // 计算前17位的权重和
        let sum = 0;
        for (let i = 0; i < 17; i++) {
            sum += Wi[i] * idBody[i];
        }

        // 计算模
        const modValue = sum % 11;

        // 获取实际的校验码
        const actualChecksum = validateCode[modValue];

        // 判断校验码是否一致
        if (actualChecksum === idChecksum || (modValue === 2 && (idChecksum === 'X' || idChecksum === 'x'))) {

        } else {
            throw new Error('请输入正确的身份证号码')
        }
    }

    validatePhone(vals) {
        // 假设我们只检查中国的手机号，格式为1xxxxxxxxxx
        // 使用正则表达式进行匹配
        const regex = /^1[3-9]\d{9}$/;
        const phone = decrypt(vals.body.phone)
        if (regex.test(phone)) {
        } else {
            throw new Error('请输入正确的手机号')
        }
    }

    validatePassword(vals) {
        // const psw1 = decrypt(vals.body.password1)
        // const psw2 = decrypt(vals.body.password2)
        // if (psw1 !== psw2) {
        //     throw new Error('两个密码必须相同')
        // }

        const encryptedPsw1 = vals.body.password1;
        const encryptedPsw2 = vals.body.password2;

        // 解密密码
        const psw1 = decrypt(encryptedPsw1);
        const psw2 = decrypt(encryptedPsw2);

        // 检查两个密码是否相同
        if (psw1 !== psw2) {
            throw new Error('两个密码必须相同');
        }

        // 验证密码长度至少6个字符
        if (psw1.length < 6) {
            throw new Error('密码至少6个字符');
        }

        // 验证密码复杂度：至少包含一个小写字母、一个大写字母、一个特殊字符和数字
        const passwordRegex = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[!@#$%^&*()_\-+=~`\{\}\[\]\|\\:;\"'<>,.\/?]).{6,}$/;
        if (!passwordRegex.test(psw1)) {
            throw new Error('密码必须包含大小写字母、特殊字符和数字');
        }
    }

    async validateEmail(vals) {
        const email = decrypt(vals.body.email)
        const user = await User.findOne({
            where: {
                email: email
            }
        })
        if (user) {
            throw new Error('email已存在')
        }
    }

    async validateEmailName(vals) {
        const encryptedEmail = vals.body.email;

        // 解密电子邮件地址
        const email = decrypt(encryptedEmail);

        // 验证电子邮件地址格式
        const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
        if (!emailRegex.test(email)) {
            throw new Error('不符合Email规范');
        }
    }

}

class TokenValidator extends LinValidator {
    constructor() {
        //隐藏的错误
        // Java
        // JS Python
        super()
        this.account = [
            new Rule('isLength', '不符合账号规则', {
                min: 4,
                max: 200
            })
        ]
        this.secret = [
            //    validator.js
            new Rule('isOptional'),
            new Rule('isLength', '至少6个字符', {
                min: 6,
                max: 128
            })
        ]
    }
}

class NotEmptyValidator extends LinValidator {
    constructor() {
        super()
        this.token = [
            new Rule('isLength', '不允许为空', {
                min: 1
            })
        ]
    }
}

function checkType(vals) {
    let type = vals.body.type || vals.path.type
    if (!type) {
        throw new Error('type是必须参数')
    }
    type = parseInt(type)

    if (!LoginType.isThisType(type)) {
        throw new Error('type参数不合法')
    }
}

function checkArtType(vals) {
    let type = vals.body.type || vals.path.type
    if (!type) {
        throw new Error('type是必须参数')
    }
    type = parseInt(type)

    if (!ArtType.isThisType(type)) {
        throw new Error('type参数不合法')
    }
}

class Checker {
    constructor(type) {
        this.enumType = type
    }

    check(vals) {
        let type = vals.body.type || vals.path.type
        if (!type) {
            throw new Error('type是必须参数')
        }
        type = parseInt(type)

        if (!this.enumType.isThisType(type)) {
            throw new Error('type参数不合法')
        }

    }
}


class LikeValidator extends PositiveIntegerValidator {
    constructor() {
        super()
        this.validateType = checkArtType
        // const checker = new Checker(ArtType)
        // this.validateType = checker.check.bind(checker)
    }
}

class ClassicValidator extends LikeValidator {

}

class SearchValidator extends LinValidator {
    constructor() {
        super()
        this.q = [
            new Rule('isLength', '搜索关键词不能为空', {
                min: 1,
                max: 16
            })
        ]
        this.start = [
            new Rule('isInt', '不符合规范', {
                min: 0,
                max: 60000
            }),
            new Rule('isOptional', '', 0)
        ]
        this.count = [
            new Rule('isInt', '不符合规范', {
                min: 1,
                max: 20
            }),
            new Rule('isOptional', '', 20)
        ]

    }
}

class AddShortCommentValidator extends PositiveIntegerValidator {
    constructor() {
        super()
        this.content = [
            new Rule('isLength', '必须在1到12个字符之间', {
                min: 1,
                max: 12
            })
        ]
    }
}

module.exports = {
    PositiveIntegerValidator,
    RegisterValidator,
    TokenValidator,
    NotEmptyValidator,
    LikeValidator,
    ClassicValidator,
    SearchValidator,
    AddShortCommentValidator,
    MainContentValidator,
    UpdatePasswordValidator,
    AdminChangeValidator
}
